#ifndef _OSSRV_SOCKETS_LINUX_H__
#define _OSSRV_SOCKETS_LINUX_H__

/*============================= Include Files ===============================*/
#if defined WIN32
	#include <winsock2.h>
	#include <time.h>
#elif defined LINUX
	#include <sys/time.h>
/*	#include <sys/utsname.h>*/
	#include <netdb.h>
    #include <sys/socket.h>
    #include <netinet/tcp.h>
    #include <arpa/inet.h>
    #include <arpa/telnet.h>
#elif defined VXWORKS
	#include <types/vxTypes.h>
	#include <vxWorks.h> 
	#include <net/uio.h>
	#include <sys/times.h>
	#include <netinet/in.h> 
	#include <netinet/tcp.h> 
	#include <hostLib.h>
	#include <ioLib.h>
	#include <netdb.h>
#else
    #error Unsupported OS

#endif

__BEGIN_DECLS


#ifdef WIN32

struct sockaddr_un {
	unsigned short sun_family;  /* AF_UNIX */
     char sun_path[108];
};


#define OSSRV_SOCKET_STARTUP \
{ \
	WSADATA wsaData; \
	if (WSAStartup(0x202,&wsaData) == SOCKET_ERROR) \
	{ \
		fprintf(stderr,"WSAStartup failed with error %d, error init external connection\n",WSAGetLastError()); \
		WSACleanup(); \
		return (SOCKET_ERROR); \
	} \
} 

#define OSSRV_SOCKET_CLEANUP WSACleanup();


#define EINPROGRESS     WSAEINPROGRESS
#define EAFNOSUPPORT    WSAEAFNOSUPPORT


# if !defined (O_NONBLOCK)
#   define O_NONBLOCK  1
# endif /* O_NONBLOCK  */

# if !defined (F_GETFL)
#   define F_GETFL 0
# endif /* F_GETFL */

# if !defined (F_SETFL)
#   define F_SETFL 0
# endif /* F_SETFL */


#else
#define OSSRV_SOCKET_STARTUP
#define OSSRV_SOCKET_CLEANUP
#define INVALID_SOCKET			-1
#define SOCKET_ERROR			-1

#endif

#if defined(WIN32) || defined(VXWORKS)
#ifndef socklen_t 
	typedef int socklen_t;
#endif
#endif


#define IAC     255
#define DONT    254
#define DO      253
#define WONT    252
#define WILL    251
#define SB      250
#define BREAK   243
#define SE      240

#define TELOPT_ECHO     1
#define TELOPT_SGA      3
#define TELOPT_STATUS   5
#define TELOPT_TTYPE    24
#define	TELOPT_NAWS		31	/* window size */
#define	TELOPT_TSPEED	32	/* terminal speed */
#define	TELOPT_LFLOW	33	/* remote flow control */
#define TELOPT_LINEMODE	34	/* Linemode option */
#define TELOPT_XDISPLOC	35	/* X Display Location */


#define OSSRV_INADDR_NONE ((unsigned long) -1)

/* OSSRV_SOCKETS_accept
** 
** The function accept a connection on a socket.
**
** Input parameter:
**              socket     : A socket that has been placed in a listening state 
** Output parameter:
**              addr       : An optional pointer to a buffer that receives the address of the connecting entity
**                           
**              addrlen    : An optional pointer to an integer that contains the length of the address 
** Return codes:
**				On success, the socket number > 0 is  returned. 
**              On error, -1 is returned,
**				
*/
int OSSRV_SOCKETS_accept (int socket, struct sockaddr *addr, socklen_t *addrlen);


/* OSSRV_SOCKETS_bind
** 
** The function associates a local address with a socket.
**
** Input parameter:
**              socket     : An unbound socket
**              addr       : The address to assign to the socket
**              addrlen    : The length of the name
** Output parameter:
** Return codes:
**				On success, zero is returned. 
**              On error, -1 is returned,
**				
*/
int OSSRV_SOCKETS_bind (int socket, const struct sockaddr *addr, socklen_t addrlen);


/* OSSRV_SOCKETS_close
** 
** The function closes an existing socket
**
** Input parameter:
**              socket     : A socket that has been placed in a listening state 
** Output parameter:
** Return codes:
**				On success, the socket number > 0 is  returned. 
**              On error, -1 is returned,
**				
*/
int OSSRV_SOCKETS_close (int  socket);


/* OSSRV_SOCKETS_connect
** 
** The function establishes a connection to a specified socket
**
** Input parameter:
**              socket     : An unbound socket
**              name       : The name to assign to the socket  
**              namelen    : The length of the name
** Output parameter:
** Return codes:
**				On success, zero is returned. 
**              On error, -1 is returned,
**				
*/
int OSSRV_SOCKETS_connect (int socket ,const struct sockaddr *name, socklen_t namelen);


/* OSSRV_SOCKETS_fcntl
** 
** The function performs one of various miscellaneous operations on socket.
** The operation in question is determined by cmd
**
** Input parameter:
**              socket    : An unbound socket
**              cmd       : Command type  
**              arg       : Command argument
** Output parameter:
** Return codes:
**				On success, zero is returned. 
**              On error, -1 is returned,
**				
*/
int OSSRV_SOCKETS_fcntl( int  socket , int  cmd , long  arg );


/* OSSRV_SOCKETS_get_host_addr
** 
** The function retrieves host information corresponding to a host name from a host database
**
** Input parameter:
**              name       : Host name
** Output parameter:
**              address    : Contains the results of a successful search for 
**              the host specified in the name parameter
** Return codes:
**				On success, zero is returned. 
**              On error, -1 is returned,
**				
*/
int OSSRV_SOCKETS_get_host_addr(const char *name, struct sockaddr_in *address);


/* OSSRV_SOCKETS_inet_addr
** 
** The function converts an ASCII string containing a valid Internet address using dot 
** notation into an Internet address number typed as an unsigned long value.
**
** Input parameter:
**              ip_address_str  : Represents a string of characters in the Internet address form
**
** Return codes:
**				On success, An unsigned long value containing a suitable binary representation 
**						    of the specified Internet address. 
**              On error, -1 is returned,
**				
*/

unsigned long OSSRV_SOCKETS_inet_addr(const char *ip_address_str);

/* OSSRV_SOCKETS_get_sock_name
** 
** The function retrieves the local name for a socket
**
** Input parameter:
**              socket     : A bound socket
** Output parameter:
**              name       : Receives the address (name) of the socket
**              namelen    : The size of the name buffer
** Return codes:
**				On success, zero is returned. 
**              On error, -1 is returned,
**				
*/
int OSSRV_SOCKETS_get_sock_name (int socket, struct sockaddr *name, socklen_t *namelen);


/* OSSRV_SOCKETS_ioctl
** 
** The function controls the I/O mode of a socket
**
** Input parameter:
**              socket     : A bound socket
**              cmd        : The command to perform on the socket 
**              val        : A parameter for cmd
** Output parameter:
** Return codes:
**				On success, zero is returned. 
**              On error, -1 is returned,
**				
*/
int OSSRV_SOCKETS_ioctl (int socket,int cmd, void *val);


/* OSSRV_SOCKETS_read
** 
** The function read data from a connected socket
**
** Input parameter:
**              socket     : A bound socket
**              len        : The length of buf
** Output parameter:
**              buf        : A buffer for the incoming data
** Return codes:
**				On success, returns the number of bytes received. 
**              On error, <=0 is returned,
**				
*/
int OSSRV_SOCKETS_read (int  socket, void *buf, size_t len);


/* OSSRV_SOCKETS_recv
** 
** The function receives data from a connected socket
**
** Input parameter:
**              socket     : A bound socket
**              len        : The length of buf
**              flags      : A flag specifying the way in which the call is made
** Output parameter:
**              buf        : A buffer for the incoming data
** Return codes:
**				On success, returns the number of bytes received. 
**              On error, <=0 is returned,
**				
*/
int OSSRV_SOCKETS_recv (int socket, void *buf, int len, unsigned int flags);


/* OSSRV_SOCKETS_recv_from
** 
** The function receives a datagram and stores the source address
**
** Input parameter:
**              socket     : A bound socket
**              len        : The length of buf
**              flags      : A flag specifying the way in which the call is made
** Output parameter:
**              buf        : A buffer for the incoming data
**              from       : An optional pointer to a buffer that will hold the source address upon return
**              fromlen    : An optional pointer to the size of the from buffer
** Return codes:
**				On success, returns the number of bytes received. 
**              On error, <=0 is returned,
**				
*/
int OSSRV_SOCKETS_recv_from (int socket, void *buf, int len, unsigned int flags,
                             struct sockaddr *from, socklen_t *fromlen);

/* OSSRV_SOCKETS_socket
** 
** The function creates a socket that is bound to a specific service provider
**
** Input parameter:
**              socket_family : An address family specification
**              type          : A type specification for the new socket
**              protocol      : A particular protocol to be used with the socket
**                              that is specific to the indicated address family
** Output parameter:
** Return codes:
**				On success, returns a descriptor referencing the new socket..
**              On error, -1 is returned,
**				
*/
int OSSRV_SOCKETS_socket (int socket_family, int type, int protocol);


/* OSSRV_SOCKETS_send_to
** 
** The function sends data to a specific destination
**
** Input parameter:
**              socket      : A bound socket
**              msg         : A buffer containing the data to be transmitted
**              len         : The length of the data in msg
**              flags       : An indicator specifying the way in which the call is made
**              to          : An optional pointer to the address of the target socket
**              tolen       : The size of the address in to      
** Output parameter:
** Return codes:
**				On success, returns total number of bytes sent, 
**               which can be less than the number indicated by len..
**              On error, -1 is returned,
**				
*/
int OSSRV_SOCKETS_send_to (int socket, const void *msg, size_t len, unsigned int flags,
                           const struct sockaddr *to, socklen_t tolen); 


/* OSSRV_SOCKETS_select
** 
** The function determines the status of one or more sockets, waiting if necessary, to perform synchronous I/O.
**
** Input parameter:
**              nfds        : This parameter is ignored; 
**                            it is included only for compatibility with Berkeley sockets
**              timeout     : The maximum time for select to wait, or NULL for blocking operation.
** Input/Output parameter:
**              readset     : An optional pointer to a set of sockets to be checked for readability. 
**              writeset    : An optional pointer to a set of sockets to be checked for writability 
**              excepts     : An optional pointer to a set of sockets to be checked for errors. 
** Return codes:
**				On success, the total number of socket handles that are ready and contained in
**               the FD_SET structures,zero if the time limit expired,
**              On error, -1 is returned,
**				
*/
int OSSRV_SOCKETS_select (int nfds, fd_set *readset, fd_set *writeset, fd_set *exceptset,
                          struct timeval *timeout);




/* OSSRV_SOCKETS_htonl
** 
** The function converts a 'unsigned int' from host to network byte order (which is big-endian)
**
** Input parameter:
**              hostlong     : A 32-bit number in host byte order
** Output parameter:
** Return codes:
**				The input value in the network byte order
**				
*/
unsigned int        OSSRV_SOCKETS_htonl (unsigned int hostlong);


/* OSSRV_SOCKETS_htons
** 
** The function converts a 'unsigned short int' from host to network byte order (which is big-endian)
**
** Input parameter:
**              hostshort     : A 16-bit number in host byte order
** Output parameter:
** Return codes:
**				The input value in the network byte order
**				
*/
unsigned short int  OSSRV_SOCKETS_htons (unsigned short int hostshort);


/* OSSRV_SOCKETS_htonl
** 
** The function converts a 'unsigned short int' from network byte order to host byte order
**
** Input parameter:
**              hostshort     : A 16-bit number in network byte order
** Output parameter:
** Return codes:
**				The input value in the host byte order
**				
*/
unsigned short int  OSSRV_SOCKETS_ntohs (unsigned short int netshort);

__END_DECLS
#endif
